Highlight.js のバンドルサイズを削減する
追記: この記事は highlight.js <= 9.18.1 の環境を想定しています。
みなさん、Hightlight.js 使ってますか?
Caramelize での codeBlock シンタックスハイライトに用いています
ところで…
https://gyazo.com/d77679227fb12d3d1e8f781ada67ac17
デカくないですか?
どうやって削減
個別 import していきましょう
hightlight.js のトップレベルには型定義がありますが、languages にはありません
使いそうなものを頑張って require していきます
code:理想.ts
"bash".map(language => {return [language, require(highlight.js/lib/languages/${language})]}) こういう記法ができれば良かったのですが
これをやると綺麗に全部読まれます(はじめにもどる)
使いそうな言語
code:使いそう.ts
export const languages: { k: string: any } = { sh: bash,
bash: bash,
coffee: coffeescript,
cpp: cpp,
cs: cs,
crystal: crystal,
css: css,
d: d,
dockerfile: dockerfile,
el: elixir,
elixir: elixir,
elm: elm,
er: erlang,
erlang: erlang,
glsl: glsl,
go: go,
hs: haskell,
java: java,
js: javascript,
javascript: javascript,
jsx: javascript,
json: json,
kt: kotlin,
kotlin: kotlin,
less: less,
lua: lua,
md: markdown,
markdown: markdown,
m: matlab,
matlab: matlab,
perl: perl,
php: php,
powershell: powershell,
python: python,
r: r,
rb: ruby,
ruby: ruby,
rs: rust,
rust: rust,
scala: scala,
scss: scss,
sql: sql,
stylus: stylus,
swift: swift,
tex: tex,
typescript: typescript,
ts: typescript,
tsx: javascript,
yml: yaml,
vue: vue,
xml: xml,
}
これを実際に使いそうなところで languages[ext] してやると存在判定ができて便利です
typescript に ts, typescript 両方の名前で登録しているのは、下でライブラリ外の定義を使う時に subLanguage として正しい名前での参照を求めるからです
ライブラリ外の定義を使う
こんなときがあります
こういう時にこうしたくなってしまいますね
code:取り込みたい.ts
import hljs from "highlight.js"
import vue from "highlightjs-vue"
hljs.registerLanguage("vue", vue)
でも、こうすると…
https://gyazo.com/72cbb16fe7f1508c49af447566b49d22
highlight.js/lib
https://gyazo.com/25afcbab69e6fdd69c18cd7693f3651f
悲しいことがありました…になってしまう
じゃあどうすれば全部入りにならずに記法を登録できるか
code:正答例.ts
// @ts-ignore /lib/highlight には定義がありません
import hljs from "highlight.js/lib/highlight"
import vue from "highlightjs-vue"
hljs.registerLanguage("vue", vue)
まあ highlightjs-vue はパッケージ形態が特殊なのでこれじゃ取り込めないんですけどね
code:highlightjs-vue の場合の正答例.ts
// @ts-ignore
import hljs from "highlight.js/lib/highlight"
// @ts-ignore
import { definer as vue } from "highlightjs-vue/dist/highlightjs-vue.esm"
hljs.registerLanguage("vue", vue)
ts-ignore ばかりのコードになってしまいました…
実際に採用しているコードでは languages に入れた後 map で登録しているので、registerLanguage はそちらで行っています
code:登録.ts
hljs.registerLanguage(language, parser)
})
結果
https://gyazo.com/d0027b12996bee4474dea73cea109479
こうして無事バンドルサイズが小さくなりました
MIT ライセンスに従ってパクってOK!